<?php

declare(strict_types=1);

namespace App\Controller;

use App\Models\Agent;
use App\Models\AgentWebsiteLetter;
use App\Models\Banner;
use App\Models\SummaryBase;
use App\Models\WechatUser;
use App\Service\WechatFactory;
use Carbon\Carbon;
use Hyperf\Database\Model\Builder;
use Hyperf\Database\Model\Relations\HasMany;
use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\GetMapping;
use Hyperf\HttpServer\Annotation\Middleware;
use Hyperf\HttpServer\Annotation\PatchMapping;
use Hyperf\Logger\LoggerFactory;
use Hyperf\SocketIOServer\SocketIO;
use Hyperf\Utils\Arr;
use Hyperf\Validation\Contract\ValidatorFactoryInterface;
use Psr\Log\LoggerInterface;
use Qbhy\HyperfAuth\AuthManager;
use Qbhy\HyperfAuth\AuthMiddleware;

/**
 * @Controller(prefix="/api/h5/v2/user")
 */
class AgentController extends AbstractController
{
    /**
     * @var LoggerInterface
     */
    protected $logger;

    /**
     * @Inject()
     * @var WechatFactory
     */
    protected $wechatFactory;

    /**
     * @Inject()
     * @var ValidatorFactoryInterface
     */
    protected $validationFactory;

    /**
     * @Inject()
     * @var AuthManager
     */
    protected $auth;

    public function __construct(LoggerFactory $loggerFactory)
    {
        $this->logger = $loggerFactory->get('log', 'default');
    }

    /**
     * 用户详情信息
     * @GetMapping(path="")
     * @Middleware(AuthMiddleware::class)
     */
    public function info()
    {
        return $this->response->json(
            tap(
                Agent::query()
                    ->with(['directInviter', 'indirectInviter', 'wechat', 'partnerIdentity',
                        'indicatorsDailySummary' => fn(HasMany $hasMany) => $hasMany
                            ->whereIn('type', [SummaryBase::TYPE_AGENT, SummaryBase::TYPE_TEAM])
                            ->where('day', Carbon::now()->format('Y-m-d')),
                        'indicatorsMonthlySummary' => fn(HasMany $hasMany) => $hasMany
                            ->whereIn('type', [SummaryBase::TYPE_AGENT, SummaryBase::TYPE_TEAM])
                            ->where('month', Carbon::now()->format('Ym'))
                    ])
                    ->withCount(['websiteLetter as unread_station_letter' => function (Builder $builder) {
                        $builder->where('status', AgentWebsiteLetter::STATUS_UNREAD);
                    }])
                    ->find($this->auth->user()->getId())
                    ->toArray(),
                function (&$agent) {
                    // 代理商 团队 统计
                    $agent['agent_indicators_daily_summary'] = null;
                    $agent['agent_indicators_monthly_summary'] = null;
                    $agent['team_indicators_daily_summary'] = null;
                    $agent['team_indicators_monthly_summary'] = null;
                    foreach ($agent['indicators_daily_summary'] as $item) {
                        if ($item['type'] === SummaryBase::TYPE_AGENT) {
                            $agent['agent_indicators_daily_summary'] = $item;
                        } elseif ($item['type'] === SummaryBase::TYPE_TEAM) {
                            $agent['team_indicators_daily_summary'] = $item;
                        }
                    }
                    foreach ($agent['indicators_monthly_summary'] as $item) {
                        if ($item['type'] === SummaryBase::TYPE_AGENT) {
                            $agent['agent_indicators_monthly_summary'] = $item;
                        } elseif ($item['type'] === SummaryBase::TYPE_TEAM) {
                            $agent['team_indicators_monthly_summary'] = $item;
                        }
                    }

                    $agent['total_balance'] = $agent['balance'] + $agent['unextractable_balance']; // 总余额

                    $agent['system'] = [
                        'banner' => Banner::query()->with('attachments')->orderBy('sort_id')->get()->toArray(), // 首页 Banner
                        'recharge_reward' => [] // 充值奖励 TODO 暂时下架
                    ];

                    // 显示团队大咖
                    $agent['team_leader'] = '省到家团队';
                    // 1. 直接/间接 邀请 是否有大咖
                    $directInviterIsStrongMan = $agent['direct_inviter'] && ($agent['direct_inviter']['level'] === Agent::LEVEL_STRONGMAN);
                    $indirectInviterIsStrongMan = $agent['indirect_inviter'] && ($agent['indirect_inviter']['level'] === Agent::LEVEL_STRONGMAN);
                    if ($directInviterIsStrongMan || $indirectInviterIsStrongMan) {
                        if ($directInviterIsStrongMan) {
                            $agent['team_leader'] = $agent['direct_inviter']['name'] . '团队';
                        } elseif ($indirectInviterIsStrongMan) {
                            $agent['team_leader'] = $agent['indirect_inviter']['name'] . '团队';
                        }
                    } else {
                        // 往上寻找合伙人
                        $parentIds = explode('-', $agent['parent_path_id']);
                        if (!empty($parentIds)) {
                            $parents = arrayCombineByKey(
                                Agent::query()
                                    ->withoutGlobalScope('created_at')
                                    ->whereHas('partnerIdentity')
                                    ->whereIn('id', $parentIds)
                                    ->get()
                                    ->toArray(),
                                'id'
                            );
                            foreach (array_reverse($parentIds) as $parentId) {
                                if (isset($parents[$parentId])) {
                                    $agent['team_leader'] = $parents[$parentId]['name'] . '团队';
                                    break;
                                }
                            }
                        }
                    }
                }
            )
        );
    }

    /**
     * 更新代理商微信信息
     * @PatchMapping(path="wechat")
     * @Middleware(AuthMiddleware::class)
     */
    public function wechat()
    {
        $weChatUser = null;
        try {
            $app = $this->wechatFactory->officialAccount();

            $wxUser = $app->oauth->user($app->oauth->getAccessToken($this->request->input('code', '')));

            $weChatUser = WechatUser::query()->updateOrCreate(
                ['openid' => $wxUser->getOriginal()['openid']],
                Arr::add(
                    Arr::only(
                        $wxUser->getOriginal(),
                        ['openid', 'nickname', 'sex', 'province', 'city', 'country', 'headimgurl', 'privilege']),
                    'agent_id',
                    $this->auth->user()->getId()
                ));
        } catch (\Exception $e) {
            $this->logger->error('更新用户微信信息发生错误: ' . $e->getMessage());
        }

        return $this->response->json($weChatUser);
    }

    /**
     * 要求前端刷新个人信息
     * @PatchMapping(path="refresh-info")
     */
    public function refreshUserInfo()
    {
        try {
            $socketIO = $this->container->get(SocketIO::class);
            $socketIO->in($this->request->input('agent_id'))->emit('event', ['type' => 'refresh-info']);
        } catch (\Exception $e) {
            $this->logger->error('发送 Socket.io 发生错误: ' . $e->getMessage());
        }
    }
}
